from redis import Redis
from typing import Optional, Dict
import time
import json
from Logger import Logger
from ConfigManager import ConfigManager

logger = Logger.get_logger(__name__)

class RedisQueue:
    def __init__(self):
        try:
            redis_url = ConfigManager().get('redis_broker')
            if not redis_url:
                raise ValueError("Redis connection URL not found in config")
            self.redis = Redis.from_url(redis_url)
        except Exception as e:
            logger.error(f"Failed to initialize RedisQueue: {str(e)}")
            raise

    def enqueue(self, topic: str, message: dict) -> bool:
        """
        向指定topic队列生产一个消息
        使用hash存储消息内容，使用sorted set维护消息顺序
        """
        try:
            topic = topic.value
            msg_id = f"{topic}:{int(time.time()*1000)}"
            uniq_id = message['uniq_id']
            # 存储消息内容到hash
            self.redis.hset(f"queue:{topic}:{uniq_id}:messages", 
                          msg_id, 
                          json.dumps(message))
            # 使用时间戳作为score添加到有序集合
            self.redis.zadd(f"queue:{topic}:{uniq_id}:order", 
                          {msg_id: time.time()})
            logger.info(f"Enqueued message {msg_id} to topic {topic}:{uniq_id}")
            return True
        except Exception as e:
            logger.error(f"Failed to enqueue message to topic {topic}:{uniq_id}: {str(e)}")
            return False

    def dequeue(self, topic: str, uniq_id: str) -> Optional[Dict]:
        """
        从指定topic队列消费一条消息
        """
        try:
            # 获取最早的消息ID
            msg_ids = self.redis.zrange(f"queue:{topic}:{uniq_id}:order", 0, 0)
            if not msg_ids:
                return None
            
            msg_id = msg_ids[0].decode()
            # 获取消息内容
            msg_content = self.redis.hget(f"queue:{topic}:{uniq_id}:messages", msg_id)
            if not msg_content:
                return None
                
            # 删除消息和顺序信息
            self.redis.hdel(f"queue:{topic}:{uniq_id}:messages", msg_id)
            self.redis.zrem(f"queue:{topic}:{uniq_id}:order", msg_id)
            
            return json.loads(msg_content)
        except Exception as e:
            logger.error(f"Failed to dequeue message from topic {topic}: {str(e)}")
            return None

    def get_topics_size(self, topic: str, uniq_id: str) -> int:
        """
        获取指定topic中未消费消息的数量
        """
        try:
            return self.redis.zcard(f"queue:{topic}:{uniq_id}:order")
        except Exception as e:
            logger.error(f"Failed to get topic size for {topic}:{uniq_id}r: {str(e)}")
            return 0
